import { Color, Component, NodePool, Sprite, Vec3, _decorator, instantiate, math, tween } from "cc";
import { MathUtil } from "../../../game/lib/kgame/util/MathUtil";
import { RandUtil } from "../../../game/lib/kgame/util/Rand";
import { GameMgr } from "../GameMgr";
import { SnakeBody } from "./SnakeBody";
const { ccclass } = _decorator;

/**
 * 食物实体
 */
@ccclass("Food")
export class Food extends Component {

    /** 对象池 */
    static POOL = new NodePool(Food);
    static get() {
        return (Food.POOL.get() || instantiate(GameMgr.ins.foodPrefab)).getComponent(Food);
    }
    static put(food: Food) {
        Food.POOL.put(food.node);
    }

    reuse() {

    }

    unuse() {
        this.eater = null;
    }

    color = new Color();
    tweenScale = new Vec3();
    eater: SnakeBody;

    /**
     * 初始化
     */
    onInit(data: kp_entity_food) {
        this.node.angle = MathUtil.rad2Deg(data.rot);
        this.node.setPosition(data.x, data.y);
        this.node.setScale(0, 0);
        this.tweenScale.set(data.size, data.size);
        this.color.fromHEX((data.color ?? RandUtil.color()).toString(16)).a = 0;
        const sprite = this.getComponent(Sprite);
        sprite.color = this.color;
        tween(this.node)
            .to(0.5, { scale: this.tweenScale }, { easing: "backOut" })
            .start();
        tween(this.color)
            .to(0.25, { a: 255 }, { easing: "quadOut", onUpdate: () => sprite.color = this.color })
            .start()

        return this;
    }

    onRemove(eater?: SnakeBody) {
        const sprite = this.getComponent(Sprite);

        if (eater) {
            //被吃
            this.eater = eater;
            tween(this.color)
                .to(0.25, { a: 0 }, { easing: "quadOut", onUpdate: () => sprite.color = this.color })
                .start();
            this.tweenScale.set(0, 0);
            tween(this.node)
                .to(0.25, { scale: this.tweenScale }, { easing: "quadOut" })
                .call(() => Food.put(this))
                .start();
        } else {
            //消失
            tween(this.color)
                .to(0.25, { a: 0 }, { easing: "quadIn", onUpdate: () => sprite.color = this.color })
                .start();
            const scale = this.node.scale.x / 4;
            this.tweenScale.set(scale, scale);
            tween(this.node)
                .to(0.25, { scale: this.tweenScale }, { easing: "quadIn" })
                .call(() => Food.put(this))
                .start();
        }
    }

    protected update(dt: number) {
        if (this.eater) {
            const { position } = this.node;
            const { position: target } = this.eater.node;
            const speed = dt * 8;
            this.node.setPosition(
                math.lerp(position.x, target.x, speed),
                math.lerp(position.y, target.y, speed)
            );
        }
    }

}